home *** CD-ROM | disk | FTP | other *** search
- ///////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- // This example code is from the book:
- //
- // Object-Oriented Programming with C++ and OSF/Motif
- // by
- // Douglas Young
- // Prentice Hall, 1992
- // ISBN 0-13-630252-1
- //
- // Copyright 1991 by Prentice Hall
- // All Rights Reserved
- //
- // Permission to use, copy, modify, and distribute this software for
- // any purpose except publication and without fee is hereby granted, provided
- // that the above copyright notice appear in all copies of the software.
- ///////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
-
- // See Board.h for comments on changes to this file from the book version.
-
-
- /////////////////////////////////////////////////////////
- // Engine.C: The brains of the tic-tac-toe game
- /////////////////////////////////////////////////////////
- #include "TicTacToe.h"
- #include "Engine.h"
- #include "GameBoard.h"
- #include "MoveGenerator.h"
- #include "Message.h"
- #include "Board.h"
- #include <stdlib.h> // Needed for exit()
-
- Engine::Engine ( TicTacToe* game )
- {
- _game = game;
- _gameOver = FALSE;
- _whoseMove = XX; // Start with X as the first move
- _board = new Board(); // Create the Engine subcomponents
- _moveGenerator = new MoveGenerator();
- }
-
- Engine::~Engine()
- {
- delete _board;
- delete _moveGenerator;
- }
-
- void Engine::reset()
- {
- _whoseMove = XX;
- _gameOver = FALSE;
- _board->clear();
- _game->gameBoard()->clear();
- _game->messageArea()->postMessage ( NEWGAMEMSG );
- }
-
- void Engine::recordMove ( int position )
- {
- if ( _gameOver ) // Don't accept moves if the game is over
- {
- _game->messageArea()->postAlert( GAMEISOVERMSG );
- return;
- }
-
- // Record the move. If it is valid, display it on the board
- // Otherwise ask the user to pick again.
-
- if ( _board->recordMove ( position, _whoseMove ) == validMove)
- {
- if(_whoseMove == XX)
- _game->gameBoard()->markX ( position );
- else
- _game->gameBoard()->markO ( position );
- }
- else
- {
- _game->messageArea()->postAlert ( ILLEGALMOVEMSG );
- return;
- }
-
- // See if this move wins the game for the user
-
- checkForWin();
-
- if ( _gameOver )
- return;
-
- // If this is the game's move, change to X's move and ask the
- // user to choose a square. If it is the user's move, change to
- // our move and pick a move. Call this function
- // recursively to record the game's choice.
-
- if ( _whoseMove == OO )
- {
- _whoseMove = XX;
- _game->messageArea()->postMessage ( USERSMOVEMSG );
- }
- else
- {
- _whoseMove = OO;
- recordMove ( _moveGenerator->getNextMove ( _board ) );
- }
- }
-
- void Engine::checkForWin()
- {
- int i, *winningSquares;
- markType winner;
-
- // If no one has won yet, just keep playing
-
- if ( ( winner = _board->whoHasWon() ) == NOBODYYET )
- {
- return;
- }
- else if ( winner == TIE)
- {
- // If it's a tie, end the game and notify the user
-
- _gameOver = TRUE;
-
- for ( i = 0 ; i < 9; i++ )
- _game->gameBoard()->deemphasizeSquare ( i );
-
- _game->messageArea()->postAlert( TIEGAMEMSG );
- }
- else // Someone won
- {
- _gameOver = TRUE;
-
- // Get the mask for the wining pattern
-
- winningSquares = _board->winningSquares();
-
- // Deactivate each square to prevent input. Highlight
- // the winning squares, and fade others into the background.
-
- for ( i = 0 ; i < 9; i++ )
- {
- _game->gameBoard()->deactivateSquare ( i );
-
- if ( winningSquares[i] )
- _game->gameBoard()->highlightSquare ( i );
- else
- _game->gameBoard()->deemphasizeSquare ( i );
- }
-
- // Finally, alert the user that someone has won
-
- if ( winner == XX )
- _game->messageArea()->postAlert ( XWINSMSG );
- else
- _game->messageArea()->postAlert ( OWINSMSG );
- }
- }
-
- void Engine::quit()
- {
- exit ( 0 );
- }
-